package com.fingard.dsp.bank.directbank.hsbc01;

import java.io.File;
import java.math.BigDecimal;
import java.util.*;

import com.fingard.dsp.bank.directbank.bankInterface.IFileResolveDifference;
import com.fingard.io.FileHelper;
import com.fingard.text.StringHelper;
import com.fingard.util.DateHelper;
import com.fingard.xml.XmlTextReader;

public class HSBC01ForeignBank extends HSBC01Base implements IFileResolveDifference {
    /**
     * MT942获取余额差异处理方法
     * @param context
     * @param accountNum
     * @param date
     * @return
     * @throws Exception
     */
    @Override
    public Map<String, String> getBalanceMap(String context, String accountNum, String date) throws Exception {
        //获取出账总金额
        int offset = context.indexOf(tag90D) + tag90D.length();
        int endset = context.indexOf(tag90C);
        String outBal = context.substring(offset, endset);
        int startIndex=indexLength(outBal.replace(",","").trim());
        outBal = outBal.substring(startIndex + 1).replaceAll(",", ".")
                .replaceAll("\r", "").replaceAll("\n", "");
        outBal = amtCheck(outBal);
        //获取入账总金额
        offset = context.indexOf(tag90C) + tag90C.length();
        endset = context.indexOf(tag86);
        String inBal = context.substring(offset, endset);
        startIndex=indexLength(inBal.replace(",","").trim());
        inBal = inBal.substring(startIndex+1).replaceAll(",", ".")
                .replaceAll("\r", "").replaceAll("\n", "");
        inBal = amtCheck(inBal);
        //获取余额相关信息
        offset = context.indexOf(tag86) + tag86.length();
        //获取交易金额
        String balance = context.substring(offset);
        //期初余额
        offset = balance.indexOf("PLGC");
        endset = balance.indexOf("/CLGC");
        String openBal = balance.substring(offset + 4, endset).replace(",", ".").trim();
        openBal = amtCheck(openBal);
        //期末余额
        offset = balance.indexOf("/CAVC");
        String closeBal = balance.substring(endset + 5, offset).replace(",", ".").trim();
        closeBal = amtCheck(closeBal);
        //当前可用余额
        String availBal = balance.substring(offset + 5).replace(",", ".").replace("-}", "").trim();
        availBal = amtCheck(availBal);
        //计算该账户上一次的当前余额：当前余额-入账+出账
        BigDecimal bigDecimal = new BigDecimal(closeBal);
        String lastBal = bigDecimal.add(new BigDecimal(outBal)).subtract(new BigDecimal(inBal)).toString();
        //返回
        Map<String,String> map=new HashMap<String, String>();
        map.put("closeBal",closeBal);
        map.put("availBal",availBal);
        map.put("openBal",openBal);
        map.put("lastBal",lastBal);
        return map;
        //return null;
    }

    /**
     * MT942的86字段获取对方信息数据差异处理方法
     * @param string86
     * @return
     * @throws Exception
     */
    @Override
    public Map<String, String> getRecInformationMap(String string86) throws Exception {
        //定义元素
        String recAct = "";//对方账户
        String recName = "";//对方名称
        String recBankName="";//对方银行名称
        String recDetail = "";//备注
        String[] detailsplit = string86.split("/");
        List<String> list = Arrays.asList(detailsplit);
        //对方账户
        if (list.indexOf("AC") != -1) {
            recAct = list.get(list.indexOf("AC") + 1).trim();
            recAct = recAct.replaceAll("\r\n", "");
        } else {
            //借贷标识为C时，银行未返回对方账户
            recAct = "";
        }
        //对方名称
        if (list.indexOf("BENM") != -1) {
            recName = list.get(list.indexOf("BENM") + 1).trim();
            recName = recName.replaceAll("\r\n", "");
        }
        if (list.indexOf("ORDP") != -1) {
            recName = list.get(list.indexOf("ORDP") + 1).trim();
            recName = recName.replaceAll("\r\n", "");
        }
        //用途
        if (list.indexOf("REMI") != -1) {
            recDetail = list.get(list.indexOf("REMI") + 1).trim();
            recDetail = recDetail.replaceAll("\r\n", "");
        }
        //返回值
        Map<String,String> map=new HashMap<String, String>();
        map.put("recAct",recAct);
        map.put("recName",recName);
        map.put("recBankName",recBankName);
        map.put("recDetail",recDetail);
        return map;
    }

    @Override
    public void analysisAckFile(String filePath) throws Exception {
        String ackFilePath=StringHelper.trimEndFileSp(getBankConfig().getValueAsString("DealedPath"));
        String[] rspStatus=new String[]{"","",""};
        if(FileHelper.existFile(filePath)){
            String content=FileHelper.readFileText(filePath,getCharset());
            WriteBankLogLn("获取ack文件内容为："+content);
            if("2".equals(getBankConfig().getValueAsString("ackAnalysisType"))){
                //获取流水号
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(content,tmpSbMsg);
                if(tmpBkReader!=null) {
                    if(tmpBkReader.getFirstText("/Document/CstmrPmtStsRpt/OrgnlGrpInfAndSts/GrpSts")!=null){
                        WriteBankLogLn("检测到ack-Lv.1文件开始处理");
                        //支付流水号
                        rspStatus[0]=tmpBkReader.getFirstText("/Document/CstmrPmtStsRpt/OrgnlGrpInfAndSts/OrgnlMsgId");
                        //支付时间
                        String orgnlCreDtTm=tmpBkReader.getFirstText("/Document/CstmrPmtStsRpt/GrpHdr/CreDtTm");
                        String payDate=DateHelper.convertD10toD8(orgnlCreDtTm.substring(0,10));
                        //一级响应状态
                        rspStatus[1]=tmpBkReader.getFirstText("/Document/CstmrPmtStsRpt/OrgnlGrpInfAndSts/GrpSts");
                        if("RJCT".equals(rspStatus[1])){
                            rspStatus[2]="文件被拒绝";
                        }else {
                            rspStatus[2]="交易处理中";
                        }
                        //生成ack处理文件
                        getAckStatus(ackFilePath,payDate,rspStatus,"1");
                        WriteBankLogLn("ack-Lv.1文件已处理");
                    }else{
                        WriteBankLogLn("检测到ack-Lv.2文件开始处理");
                        String reqIds="";
                        String batch="";
                        String payDate="";
                        while (tmpBkReader.read("/Document/CstmrPmtStsRpt/OrgnlPmtInfAndSts")){
                            //批次号
                            batch=tmpBkReader.readedXElement.getSingleTextNotNull("OrgnlPmtInfId");
                            //单笔的支付流水号
                            rspStatus[0]=tmpBkReader.readedXElement.getSingleChild("TxInfAndSts")
                                    .getSingleTextNotNull("OrgnlEndToEndId");
                            if(!batch.equals(rspStatus[0])){
                                reqIds+=rspStatus[0]+"@";
                            }
                            //支付时间
                            String orgnlCreDtTm=tmpBkReader.readedXElement.getSingleChild("TxInfAndSts")
                                    .getSingleChild("OrgnlTxRef").getSingleTextNotNull("ReqdExctnDt");
                            payDate=DateHelper.convertD10toD8(orgnlCreDtTm);
                            //二级响应状态
                            rspStatus[1]=tmpBkReader.readedXElement.getSingleChild("TxInfAndSts").getSingleTextNotNull("TxSts");
                            if("RJCT".equals(rspStatus[1])){
                                rspStatus[2]="文件被拒绝";
                            }else{
                                rspStatus[2]="交易处理中";
                            }
                            //生成ack处理文件
                            getAckStatus(ackFilePath,payDate,rspStatus,"2");
                            WriteBankLogLn("ack-Lv.2文件已处理");
                        }
                        if(StringHelper.hasAnyChar(reqIds)){
                            String contents=batch+"@"+reqIds+"###";
                            String ackFile=ackFilePath+File.separator+payDate+File.separator+"batch.txt";
                            //写入文件
                            FileHelper.appendFile(ackFile, contents, getCharset());
                        }
                    }
                }else{
                    WriteBankLogLn("文件"+filePath+"异常："+tmpSbMsg.toString());
                }
            }else{
                //说明是Lv1级响应
                if(filePath.contains("OCA")){
                    WriteBankLogLn("检测到ack-Lv.1文件开始处理");
                    //获取流水号
                    StringBuilder tmpSbMsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(content,tmpSbMsg);
                    if(tmpBkReader!=null) {
                        //支付流水号
                        rspStatus[0]=tmpBkReader.getFirstText("/Document/CstmrPmtStsRpt/OrgnlGrpInfAndSts/OrgnlMsgId");
                        //支付时间
                        String orgnlCreDtTm=tmpBkReader.getFirstText("/Document/CstmrPmtStsRpt/GrpHdr/CreDtTm");
                        String payDate=DateHelper.convertD10toD8(orgnlCreDtTm.substring(0,10));
                        //一级响应状态
                        rspStatus[1]=tmpBkReader.getFirstText("/Document/CstmrPmtStsRpt/OrgnlGrpInfAndSts/GrpSts");
                        if("RJCT".equals(rspStatus[1])){
                            rspStatus[2]="文件被拒绝";
                        }else {
                            rspStatus[2]="交易处理中";
                        }
                        //生成ack处理文件
                        getAckStatus(ackFilePath,payDate,rspStatus,"1");
                        WriteBankLogLn("ack-Lv.1文件已处理");
                    }else{
                        WriteBankLogLn("文件"+filePath+"异常："+tmpSbMsg.toString());
                    }
                    //说明是Lv2响应
                } else if(filePath.contains("XHK") || filePath.contains("XXX") || filePath.contains("XCN")){
                    StringBuilder tmpSbMsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(content,tmpSbMsg);
                    if(tmpBkReader!=null) {
                        String reqIds="";
                        String batch="";
                        String payDate="";
                        while (tmpBkReader.read("/Document/CstmrPmtStsRpt/OrgnlPmtInfAndSts")){
                            //批次号
                            batch=tmpBkReader.readedXElement.getSingleTextNotNull("OrgnlPmtInfId");
                            //单笔的支付流水号
                            rspStatus[0]=tmpBkReader.readedXElement.getSingleChild("TxInfAndSts")
                                    .getSingleTextNotNull("OrgnlEndToEndId");
                            if(!batch.equals(rspStatus[0])){
                                reqIds+=rspStatus[0]+"@";
                            }
                            //支付时间
                            String orgnlCreDtTm=tmpBkReader.readedXElement.getSingleChild("TxInfAndSts")
                                    .getSingleChild("OrgnlTxRef").getSingleTextNotNull("ReqdExctnDt");
                            payDate=DateHelper.convertD10toD8(orgnlCreDtTm);
                            //二级响应状态
                            rspStatus[1]=tmpBkReader.readedXElement.getSingleChild("TxInfAndSts").getSingleTextNotNull("TxSts");
                            if("RJCT".equals(rspStatus[1])){
                                rspStatus[2]="文件被拒绝";
                            }else{
                                rspStatus[2]="交易处理中";
                            }
                            //生成ack处理文件
                            getAckStatus(ackFilePath,payDate,rspStatus,"2");
                            WriteBankLogLn("ack-Lv.2文件已处理");
                        }
                        if(StringHelper.hasAnyChar(reqIds)){
                            String contents=batch+"@"+reqIds+"###";
                            String ackFile=ackFilePath+File.separator+payDate+File.separator+"batch.txt";
                            //写入文件
                            FileHelper.appendFile(ackFile, contents, getCharset());
                        }
                    }else {
                        WriteBankLogLn("文件"+filePath+"异常："+tmpSbMsg.toString());
                        throw new Exception("文件"+filePath+"异常："+tmpSbMsg.toString());
                    }
                }else {
                    WriteBankLogLn("文件"+filePath+"非Lv1、Lv2文件");
                    throw new Exception("文件"+filePath+"非Lv1、Lv2文件");
                }
            }
        }else{
            WriteBankLogLn("文件"+filePath+"不存在");
            throw new Exception("文件"+filePath+"不存在");
        }
    }
}
